home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP11.ZIP / CHAP11 / HSCHMOO / HSCHMOO.CPP < prev    next >
C/C++ Source or Header  |  1993-06-13  |  8KB  |  362 lines

  1. /*
  2.  * HSCHMOO.CPP
  3.  * Handler for Schmoo, Chapter 11.
  4.  *
  5.  * DLL exports for an object handler as well as class factory.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #define INITGUIDS
  18. #include "hschmoo.h"
  19.  
  20.  
  21. //Count number of objects and number of locks.
  22. ULONG       g_cObj=0;
  23. ULONG       g_cLock=0;
  24.  
  25. //DLL Instance handle
  26. HINSTANCE   hgInst;
  27.  
  28.  
  29. /*
  30.  * LibMain
  31.  *
  32.  * Purpose:
  33.  *  DLL-specific entry point called from LibEntry.
  34.  *
  35.  * Parameters:
  36.  *  hInst           HINSTANCE instance of the DLL.
  37.  *  wDataSeg        WORD segment selector of the DLL's data segment.
  38.  *  wHeapSize       WORD byte count of the heap.
  39.  *  lpCmdLine       LPSTR to command line used to start the module.
  40.  *
  41.  * Return Value:
  42.  *  HANDLE          Instance handle of the DLL.
  43.  *
  44.  */
  45.  
  46. HANDLE FAR PASCAL LibMain(HINSTANCE hInst, WORD wDataSeg
  47.     , WORD cbHeapSize, LPSTR lpCmdLine)
  48.     {
  49.     if (0!=cbHeapSize)
  50.         UnlockData(0);
  51.  
  52.     hgInst=hInst;
  53.     return hInst;
  54.     }
  55.  
  56.  
  57.  
  58.  
  59.  
  60. /*
  61.  * WEP
  62.  *
  63.  * Purpose:
  64.  *  Required DLL Exit function.  Does nothing.
  65.  *
  66.  * Parameters:
  67.  *  bSystemExit     BOOL indicating if the system is being shut
  68.  *                  down or the DLL has just been unloaded.
  69.  *
  70.  * Return Value:
  71.  *  void
  72.  *
  73.  */
  74.  
  75. void FAR PASCAL WEP(int bSystemExit)
  76.     {
  77.     return;
  78.     }
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85. /*
  86.  * DllGetClassObject
  87.  *
  88.  * Purpose:
  89.  *  Provides an IClassFactory for a given CLSID that this DLL is
  90.  *  registered to support.  This DLL is placed under the CLSID
  91.  *  in the registration database as the InProcServer.
  92.  *
  93.  * Parameters:
  94.  *  clsID           REFCLSID that identifies the class factory desired.
  95.  *                  Since this parameter is passed this DLL can handle
  96.  *                  any number of objects simply by returning different
  97.  *                  class factories here for different CLSIDs.
  98.  *
  99.  *  riid            REFIID specifying the interface the caller wants
  100.  *                  on the class object, usually IID_ClassFactory.
  101.  *
  102.  *  ppv             LPVOID FAR * in which to return the interface pointer.
  103.  *
  104.  * Return Value:
  105.  *  HRESULT         NOERROR on success, otherwise contains an error SCODE.
  106.  */
  107.  
  108. HRESULT __export FAR PASCAL DllGetClassObject(REFCLSID rclsid, REFIID riid
  109.     , LPVOID FAR *ppv)
  110.     {
  111.     if (!IsEqualCLSID(rclsid, CLSID_Schmoo2Figure))
  112.         return ResultFromScode(E_FAIL);
  113.  
  114.     //Check that we can provide the interface
  115.     if (!IsEqualIID(riid, IID_IUnknown) && !IsEqualIID(riid, IID_IClassFactory))
  116.         return ResultFromScode(E_NOINTERFACE);
  117.  
  118.     //Return our IClassFactory for Figure objects
  119.     *ppv=(LPVOID)new CFigureClassFactory;
  120.  
  121.     if (NULL==*ppv)
  122.         return ResultFromScode(E_OUTOFMEMORY);
  123.  
  124.     //Don't forget to AddRef the object through any interface we return
  125.     ((LPUNKNOWN)*ppv)->AddRef();
  126.  
  127.     return NOERROR;
  128.     }
  129.  
  130.  
  131.  
  132.  
  133.  
  134. /*
  135.  * DllCanUnloadNow
  136.  *
  137.  * Purpose:
  138.  *  Answers if the DLL can be freed, that is, if there are no
  139.  *  references to anything this DLL provides.
  140.  *
  141.  * Parameters:
  142.  *  None
  143.  *
  144.  * Return Value:
  145.  *  BOOL            TRUE if nothing is using us, FALSE otherwise.
  146.  */
  147.  
  148. STDAPI DllCanUnloadNow(void)
  149.     {
  150.     SCODE   sc;
  151.  
  152.     //Our answer is whether there are any object or locks
  153.     sc=(0L==g_cObj && 0==g_cLock) ? S_OK : S_FALSE;
  154.     return ResultFromScode(sc);
  155.     }
  156.  
  157.  
  158.  
  159.  
  160. /*
  161.  * ObjectDestroyed
  162.  *
  163.  * Purpose:
  164.  *  Function for the Figure object to call when it gets destroyed.
  165.  *  Since we're in a DLL we only track the number of objects here
  166.  *  letting DllCanUnloadNow take care of the rest.
  167.  *
  168.  * Parameters:
  169.  *  None
  170.  *
  171.  * Return Value:
  172.  *  None
  173.  */
  174.  
  175. void FAR PASCAL ObjectDestroyed(void)
  176.     {
  177.     g_cObj--;
  178.     return;
  179.     }
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186. /*
  187.  * CFigureClassFactory::CFigureClassFactory
  188.  *
  189.  * Purpose:
  190.  *  Constructor for an object supporting an IClassFactory that
  191.  *  instantiates Figure objects.
  192.  *
  193.  * Parameters:
  194.  *  None
  195.  */
  196.  
  197. CFigureClassFactory::CFigureClassFactory(void)
  198.     {
  199.     m_cRef =0L;
  200.     return;
  201.     }
  202.  
  203.  
  204.  
  205.  
  206.  
  207. /*
  208.  * CFigureClassFactory::~CFigureClassFactory
  209.  *
  210.  * Purpose:
  211.  *  Destructor for a CFigureClassFactory object.  This will be
  212.  *  called when we ::Release the object to a zero reference count.
  213.  */
  214.  
  215. CFigureClassFactory::~CFigureClassFactory(void)
  216.     {
  217.     return;
  218.     }
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225. /*
  226.  * CFigureClassFactory::QueryInterface
  227.  * CFigureClassFactory::AddRef
  228.  * CFigureClassFactory::Release
  229.  *
  230.  * Purpose:
  231.  *  IUnknown implementations for this object.
  232.  */
  233.  
  234. STDMETHODIMP CFigureClassFactory::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  235.     {
  236.     *ppv=NULL;
  237.  
  238.     //Any interface on this object is the object pointer.
  239.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  240.         *ppv=(LPVOID)this;
  241.  
  242.     /*
  243.      * If we actually assign an interface to ppv we need to AddRef it
  244.      * since we're returning a new pointer.
  245.      */
  246.     if (NULL!=*ppv)
  247.         {
  248.         ((LPUNKNOWN)*ppv)->AddRef();
  249.         return NOERROR;
  250.         }
  251.  
  252.     return ResultFromScode(E_NOINTERFACE);
  253.     }
  254.  
  255.  
  256. STDMETHODIMP_(ULONG) CFigureClassFactory::AddRef(void)
  257.     {
  258.     return ++m_cRef;
  259.     }
  260.  
  261.  
  262. STDMETHODIMP_(ULONG) CFigureClassFactory::Release(void)
  263.     {
  264.     ULONG           cRefT;
  265.  
  266.     cRefT=--m_cRef;
  267.  
  268.     if (0L==m_cRef)
  269.         delete this;
  270.  
  271.     return cRefT;
  272.     }
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280. /*
  281.  * CFigureClassFactory::CreateInstance
  282.  *
  283.  * Purpose:
  284.  *  Instantiates a Figure object that supports the IFigure
  285.  *  and IUnknown interfaces.  If the caller asks for a different
  286.  *  interface than these two then we fail.
  287.  *
  288.  * Parameters:
  289.  *  punkOuter       LPUNKNOWN to the controlling IUnknown if we are
  290.  *                  being used in an aggregation.
  291.  *  riid            REFIID identifying the interface the caller desires
  292.  *                  to have for the new object.
  293.  *  ppvObj          LPVOID FAR * in which to store the desired interface
  294.  *                  pointer for the new object.
  295.  *
  296.  * Return Value:
  297.  *  HRESULT         NOERROR if successful, otherwise contains E_NOINTERFACE
  298.  *                  if we cannot support the requested interface.
  299.  */
  300.  
  301. STDMETHODIMP CFigureClassFactory::CreateInstance(LPUNKNOWN punkOuter
  302.     , REFIID riid, LPVOID FAR *ppvObj)
  303.     {
  304.     LPCFigure           pObj;
  305.     HRESULT             hr;
  306.  
  307.     *ppvObj=NULL;
  308.     hr=ResultFromScode(E_OUTOFMEMORY);
  309.  
  310.     //Verify that if there is a controlling unknown it's asking for IUnknown
  311.     if (NULL!=punkOuter && !IsEqualIID(riid, IID_IUnknown))
  312.         return ResultFromScode(E_NOINTERFACE);
  313.  
  314.     //Create the object.  This also creates a window.
  315.     pObj=new CFigure(punkOuter, ObjectDestroyed, hgInst);
  316.  
  317.     if (NULL==pObj)
  318.         return hr;
  319.  
  320.     if (pObj->FInit())
  321.         hr=pObj->QueryInterface(riid, ppvObj);
  322.  
  323.     //Kill the object if initial creation or FInit failed.
  324.     if (FAILED(hr))
  325.         delete pObj;
  326.     else
  327.         g_cObj++;
  328.  
  329.     return hr;
  330.     }
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337. /*
  338.  * CFigureClassFactory::LockServer
  339.  *
  340.  * Purpose:
  341.  *  Increments or decrements the lock count of the DLL.  If the lock
  342.  *  count goes to zero and there are no objects, the DLL is allowed
  343.  *  to unload.  See DllCanUnloadNow.
  344.  *
  345.  * Parameters:
  346.  *  fLock           BOOL specifying whether to increment or decrement the
  347.  *                  lock count.
  348.  *
  349.  * Return Value:
  350.  *  HRESULT         NOERROR always.
  351.  */
  352.  
  353. STDMETHODIMP CFigureClassFactory::LockServer(BOOL fLock)
  354.     {
  355.     if (fLock)
  356.         g_cLock++;
  357.     else
  358.         g_cLock--;
  359.  
  360.     return NOERROR;
  361.     }
  362.